home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume13 / rpc3.9 / part05 < prev    next >
Encoding:
Internet Message Format  |  1988-02-27  |  60.2 KB

  1. Subject:  v13i082:  Sun RPC, release 3.9, Part05/15
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Stephen X. Nahm <sxn@Sun.COM>
  7. Posting-number: Volume 13, Issue 82
  8. Archive-name: rpc3.9/part05
  9.  
  10. #! /bin/sh
  11. # This is a shell archive. To extract, remove the header and type "sh filename"
  12. #
  13. cd rpc
  14. echo x - xdr.c
  15. cat > xdr.c <<'Funky_Stuff'
  16. /* @(#)xdr.c    1.1 87/11/04 3.9 RPCSRC */
  17. /*
  18.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  19.  * unrestricted use provided that this legend is included on all tape
  20.  * media and as a part of the software program in whole or part.  Users
  21.  * may copy or modify Sun RPC without charge, but are not authorized
  22.  * to license or distribute it to anyone else except as part of a product or
  23.  * program developed by the user.
  24.  * 
  25.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  26.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  27.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  28.  * 
  29.  * Sun RPC is provided with no support and without any obligation on the
  30.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  31.  * modification or enhancement.
  32.  * 
  33.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  34.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  35.  * OR ANY PART THEREOF.
  36.  * 
  37.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  38.  * or profits or other special, indirect and consequential damages, even if
  39.  * Sun has been advised of the possibility of such damages.
  40.  * 
  41.  * Sun Microsystems, Inc.
  42.  * 2550 Garcia Avenue
  43.  * Mountain View, California  94043
  44.  */
  45. #if !defined(lint) && defined(SCCSIDS)
  46. static char sccsid[] = "@(#)xdr.c 1.35 87/08/12";
  47. #endif
  48.  
  49. /*
  50.  * xdr.c, Generic XDR routines implementation.
  51.  *
  52.  * Copyright (C) 1986, Sun Microsystems, Inc.
  53.  *
  54.  * These are the "generic" xdr routines used to serialize and de-serialize
  55.  * most common data items.  See xdr.h for more info on the interface to
  56.  * xdr.
  57.  */
  58.  
  59. #include <stdio.h>
  60. char *malloc();
  61.  
  62. #include <rpc/types.h>
  63. #include <rpc/xdr.h>
  64.  
  65. /*
  66.  * constants specific to the xdr "protocol"
  67.  */
  68. #define XDR_FALSE    ((long) 0)
  69. #define XDR_TRUE    ((long) 1)
  70. #define LASTUNSIGNED    ((u_int) 0-1)
  71.  
  72. /*
  73.  * for unit alignment
  74.  */
  75. static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
  76.  
  77. /*
  78.  * Free a data structure using XDR
  79.  * Not a filter, but a convenient utility nonetheless
  80.  */
  81. void
  82. xdr_free(proc, objp)
  83.     xdrproc_t proc;
  84.     char *objp;
  85. {
  86.     XDR x;
  87.     
  88.     x.x_op = XDR_FREE;
  89.     (*proc)(&x, objp);
  90. }
  91.  
  92. /*
  93.  * XDR nothing
  94.  */
  95. bool_t
  96. xdr_void(/* xdrs, addr */)
  97.     /* XDR *xdrs; */
  98.     /* caddr_t addr; */
  99. {
  100.  
  101.     return (TRUE);
  102. }
  103.  
  104. /*
  105.  * XDR integers
  106.  */
  107. bool_t
  108. xdr_int(xdrs, ip)
  109.     XDR *xdrs;
  110.     int *ip;
  111. {
  112.  
  113. #ifdef lint
  114.     (void) (xdr_short(xdrs, (short *)ip));
  115.     return (xdr_long(xdrs, (long *)ip));
  116. #else
  117.     if (sizeof (int) == sizeof (long)) {
  118.         return (xdr_long(xdrs, (long *)ip));
  119.     } else {
  120.         return (xdr_short(xdrs, (short *)ip));
  121.     }
  122. #endif
  123. }
  124.  
  125. /*
  126.  * XDR unsigned integers
  127.  */
  128. bool_t
  129. xdr_u_int(xdrs, up)
  130.     XDR *xdrs;
  131.     u_int *up;
  132. {
  133.  
  134. #ifdef lint
  135.     (void) (xdr_short(xdrs, (short *)up));
  136.     return (xdr_u_long(xdrs, (u_long *)up));
  137. #else
  138.     if (sizeof (u_int) == sizeof (u_long)) {
  139.         return (xdr_u_long(xdrs, (u_long *)up));
  140.     } else {
  141.         return (xdr_short(xdrs, (short *)up));
  142.     }
  143. #endif
  144. }
  145.  
  146. /*
  147.  * XDR long integers
  148.  * same as xdr_u_long - open coded to save a proc call!
  149.  */
  150. bool_t
  151. xdr_long(xdrs, lp)
  152.     register XDR *xdrs;
  153.     long *lp;
  154. {
  155.  
  156.     if (xdrs->x_op == XDR_ENCODE)
  157.         return (XDR_PUTLONG(xdrs, lp));
  158.  
  159.     if (xdrs->x_op == XDR_DECODE)
  160.         return (XDR_GETLONG(xdrs, lp));
  161.  
  162.     if (xdrs->x_op == XDR_FREE)
  163.         return (TRUE);
  164.  
  165.     return (FALSE);
  166. }
  167.  
  168. /*
  169.  * XDR unsigned long integers
  170.  * same as xdr_long - open coded to save a proc call!
  171.  */
  172. bool_t
  173. xdr_u_long(xdrs, ulp)
  174.     register XDR *xdrs;
  175.     u_long *ulp;
  176. {
  177.  
  178.     if (xdrs->x_op == XDR_DECODE)
  179.         return (XDR_GETLONG(xdrs, (long *)ulp));
  180.     if (xdrs->x_op == XDR_ENCODE)
  181.         return (XDR_PUTLONG(xdrs, (long *)ulp));
  182.     if (xdrs->x_op == XDR_FREE)
  183.         return (TRUE);
  184.     return (FALSE);
  185. }
  186.  
  187. /*
  188.  * XDR short integers
  189.  */
  190. bool_t
  191. xdr_short(xdrs, sp)
  192.     register XDR *xdrs;
  193.     short *sp;
  194. {
  195.     long l;
  196.  
  197.     switch (xdrs->x_op) {
  198.  
  199.     case XDR_ENCODE:
  200.         l = (long) *sp;
  201.         return (XDR_PUTLONG(xdrs, &l));
  202.  
  203.     case XDR_DECODE:
  204.         if (!XDR_GETLONG(xdrs, &l)) {
  205.             return (FALSE);
  206.         }
  207.         *sp = (short) l;
  208.         return (TRUE);
  209.  
  210.     case XDR_FREE:
  211.         return (TRUE);
  212.     }
  213.     return (FALSE);
  214. }
  215.  
  216. /*
  217.  * XDR unsigned short integers
  218.  */
  219. bool_t
  220. xdr_u_short(xdrs, usp)
  221.     register XDR *xdrs;
  222.     u_short *usp;
  223. {
  224.     u_long l;
  225.  
  226.     switch (xdrs->x_op) {
  227.  
  228.     case XDR_ENCODE:
  229.         l = (u_long) *usp;
  230.         return (XDR_PUTLONG(xdrs, &l));
  231.  
  232.     case XDR_DECODE:
  233.         if (!XDR_GETLONG(xdrs, &l)) {
  234.             return (FALSE);
  235.         }
  236.         *usp = (u_short) l;
  237.         return (TRUE);
  238.  
  239.     case XDR_FREE:
  240.         return (TRUE);
  241.     }
  242.     return (FALSE);
  243. }
  244.  
  245.  
  246. /*
  247.  * XDR a char
  248.  */
  249. bool_t
  250. xdr_char(xdrs, cp)
  251.     XDR *xdrs;
  252.     char *cp;
  253. {
  254.     int i;
  255.  
  256.     i = (*cp);
  257.     if (!xdr_int(xdrs, &i)) {
  258.         return (FALSE);
  259.     }
  260.     *cp = i;
  261.     return (TRUE);
  262. }
  263.  
  264. /*
  265.  * XDR an unsigned char
  266.  */
  267. bool_t
  268. xdr_u_char(xdrs, cp)
  269.     XDR *xdrs;
  270.     char *cp;
  271. {
  272.     u_int u;
  273.  
  274.     u = (*cp);
  275.     if (!xdr_u_int(xdrs, &u)) {
  276.         return (FALSE);
  277.     }
  278.     *cp = u;
  279.     return (TRUE);
  280. }
  281.  
  282. /*
  283.  * XDR booleans
  284.  */
  285. bool_t
  286. xdr_bool(xdrs, bp)
  287.     register XDR *xdrs;
  288.     bool_t *bp;
  289. {
  290.     long lb;
  291.  
  292.     switch (xdrs->x_op) {
  293.  
  294.     case XDR_ENCODE:
  295.         lb = *bp ? XDR_TRUE : XDR_FALSE;
  296.         return (XDR_PUTLONG(xdrs, &lb));
  297.  
  298.     case XDR_DECODE:
  299.         if (!XDR_GETLONG(xdrs, &lb)) {
  300.             return (FALSE);
  301.         }
  302.         *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
  303.         return (TRUE);
  304.  
  305.     case XDR_FREE:
  306.         return (TRUE);
  307.     }
  308.     return (FALSE);
  309. }
  310.  
  311. /*
  312.  * XDR enumerations
  313.  */
  314. bool_t
  315. xdr_enum(xdrs, ep)
  316.     XDR *xdrs;
  317.     enum_t *ep;
  318. {
  319. #ifndef lint
  320.     enum sizecheck { SIZEVAL };    /* used to find the size of an enum */
  321.  
  322.     /*
  323.      * enums are treated as ints
  324.      */
  325.     if (sizeof (enum sizecheck) == sizeof (long)) {
  326.         return (xdr_long(xdrs, (long *)ep));
  327.     } else if (sizeof (enum sizecheck) == sizeof (short)) {
  328.         return (xdr_short(xdrs, (short *)ep));
  329.     } else {
  330.         return (FALSE);
  331.     }
  332. #else
  333.     (void) (xdr_short(xdrs, (short *)ep));
  334.     return (xdr_long(xdrs, (long *)ep));
  335. #endif
  336. }
  337.  
  338. /*
  339.  * XDR opaque data
  340.  * Allows the specification of a fixed size sequence of opaque bytes.
  341.  * cp points to the opaque object and cnt gives the byte length.
  342.  */
  343. bool_t
  344. xdr_opaque(xdrs, cp, cnt)
  345.     register XDR *xdrs;
  346.     caddr_t cp;
  347.     register u_int cnt;
  348. {
  349.     register u_int rndup;
  350.     static crud[BYTES_PER_XDR_UNIT];
  351.  
  352.     /*
  353.      * if no data we are done
  354.      */
  355.     if (cnt == 0)
  356.         return (TRUE);
  357.  
  358.     /*
  359.      * round byte count to full xdr units
  360.      */
  361.     rndup = cnt % BYTES_PER_XDR_UNIT;
  362.     if (rndup > 0)
  363.         rndup = BYTES_PER_XDR_UNIT - rndup;
  364.  
  365.     if (xdrs->x_op == XDR_DECODE) {
  366.         if (!XDR_GETBYTES(xdrs, cp, cnt)) {
  367.             return (FALSE);
  368.         }
  369.         if (rndup == 0)
  370.             return (TRUE);
  371.         return (XDR_GETBYTES(xdrs, crud, rndup));
  372.     }
  373.  
  374.     if (xdrs->x_op == XDR_ENCODE) {
  375.         if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
  376.             return (FALSE);
  377.         }
  378.         if (rndup == 0)
  379.             return (TRUE);
  380.         return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
  381.     }
  382.  
  383.     if (xdrs->x_op == XDR_FREE) {
  384.         return (TRUE);
  385.     }
  386.  
  387.     return (FALSE);
  388. }
  389.  
  390. /*
  391.  * XDR counted bytes
  392.  * *cpp is a pointer to the bytes, *sizep is the count.
  393.  * If *cpp is NULL maxsize bytes are allocated
  394.  */
  395. bool_t
  396. xdr_bytes(xdrs, cpp, sizep, maxsize)
  397.     register XDR *xdrs;
  398.     char **cpp;
  399.     register u_int *sizep;
  400.     u_int maxsize;
  401. {
  402.     register char *sp = *cpp;  /* sp is the actual string pointer */
  403.     register u_int nodesize;
  404.  
  405.     /*
  406.      * first deal with the length since xdr bytes are counted
  407.      */
  408.     if (! xdr_u_int(xdrs, sizep)) {
  409.         return (FALSE);
  410.     }
  411.     nodesize = *sizep;
  412.     if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
  413.         return (FALSE);
  414.     }
  415.  
  416.     /*
  417.      * now deal with the actual bytes
  418.      */
  419.     switch (xdrs->x_op) {
  420.  
  421.     case XDR_DECODE:
  422.         if (nodesize == 0) {
  423.             return (TRUE);
  424.         }
  425.         if (sp == NULL) {
  426.             *cpp = sp = (char *)mem_alloc(nodesize);
  427.         }
  428.         if (sp == NULL) {
  429.             (void) fprintf(stderr, "xdr_bytes: out of memory\n");
  430.             return (FALSE);
  431.         }
  432.         /* fall into ... */
  433.  
  434.     case XDR_ENCODE:
  435.         return (xdr_opaque(xdrs, sp, nodesize));
  436.  
  437.     case XDR_FREE:
  438.         if (sp != NULL) {
  439.             mem_free(sp, nodesize);
  440.             *cpp = NULL;
  441.         }
  442.         return (TRUE);
  443.     }
  444.     return (FALSE);
  445. }
  446.  
  447. /*
  448.  * Implemented here due to commonality of the object.
  449.  */
  450. bool_t
  451. xdr_netobj(xdrs, np)
  452.     XDR *xdrs;
  453.     struct netobj *np;
  454. {
  455.  
  456.     return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
  457. }
  458.  
  459. /*
  460.  * XDR a descriminated union
  461.  * Support routine for discriminated unions.
  462.  * You create an array of xdrdiscrim structures, terminated with
  463.  * an entry with a null procedure pointer.  The routine gets
  464.  * the discriminant value and then searches the array of xdrdiscrims
  465.  * looking for that value.  It calls the procedure given in the xdrdiscrim
  466.  * to handle the discriminant.  If there is no specific routine a default
  467.  * routine may be called.
  468.  * If there is no specific or default routine an error is returned.
  469.  */
  470. bool_t
  471. xdr_union(xdrs, dscmp, unp, choices, dfault)
  472.     register XDR *xdrs;
  473.     enum_t *dscmp;        /* enum to decide which arm to work on */
  474.     char *unp;        /* the union itself */
  475.     struct xdr_discrim *choices;    /* [value, xdr proc] for each arm */
  476.     xdrproc_t dfault;    /* default xdr routine */
  477. {
  478.     register enum_t dscm;
  479.  
  480.     /*
  481.      * we deal with the discriminator;  it's an enum
  482.      */
  483.     if (! xdr_enum(xdrs, dscmp)) {
  484.         return (FALSE);
  485.     }
  486.     dscm = *dscmp;
  487.  
  488.     /*
  489.      * search choices for a value that matches the discriminator.
  490.      * if we find one, execute the xdr routine for that value.
  491.      */
  492.     for (; choices->proc != NULL_xdrproc_t; choices++) {
  493.         if (choices->value == dscm)
  494.             return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
  495.     }
  496.  
  497.     /*
  498.      * no match - execute the default xdr routine if there is one
  499.      */
  500.     return ((dfault == NULL_xdrproc_t) ? FALSE :
  501.         (*dfault)(xdrs, unp, LASTUNSIGNED));
  502. }
  503.  
  504.  
  505. /*
  506.  * Non-portable xdr primitives.
  507.  * Care should be taken when moving these routines to new architectures.
  508.  */
  509.  
  510.  
  511. /*
  512.  * XDR null terminated ASCII strings
  513.  * xdr_string deals with "C strings" - arrays of bytes that are
  514.  * terminated by a NULL character.  The parameter cpp references a
  515.  * pointer to storage; If the pointer is null, then the necessary
  516.  * storage is allocated.  The last parameter is the max allowed length
  517.  * of the string as specified by a protocol.
  518.  */
  519. bool_t
  520. xdr_string(xdrs, cpp, maxsize)
  521.     register XDR *xdrs;
  522.     char **cpp;
  523.     u_int maxsize;
  524. {
  525.     register char *sp = *cpp;  /* sp is the actual string pointer */
  526.     u_int size;
  527.     u_int nodesize;
  528.  
  529.     /*
  530.      * first deal with the length since xdr strings are counted-strings
  531.      */
  532.     switch (xdrs->x_op) {
  533.     case XDR_FREE:
  534.         if (sp == NULL) {
  535.             return(TRUE);    /* already free */
  536.         }
  537.         /* fall through... */
  538.     case XDR_ENCODE:
  539.         size = strlen(sp);
  540.         break;
  541.     }
  542.     if (! xdr_u_int(xdrs, &size)) {
  543.         return (FALSE);
  544.     }
  545.     if (size > maxsize) {
  546.         return (FALSE);
  547.     }
  548.     nodesize = size + 1;
  549.  
  550.     /*
  551.      * now deal with the actual bytes
  552.      */
  553.     switch (xdrs->x_op) {
  554.  
  555.     case XDR_DECODE:
  556.         if (nodesize == 0) {
  557.             return (TRUE);
  558.         }
  559.         if (sp == NULL)
  560.             *cpp = sp = (char *)mem_alloc(nodesize);
  561.         if (sp == NULL) {
  562.             (void) fprintf(stderr, "xdr_string: out of memory\n");
  563.             return (FALSE);
  564.         }
  565.         sp[size] = 0;
  566.         /* fall into ... */
  567.  
  568.     case XDR_ENCODE:
  569.         return (xdr_opaque(xdrs, sp, size));
  570.  
  571.     case XDR_FREE:
  572.         mem_free(sp, nodesize);
  573.         *cpp = NULL;
  574.         return (TRUE);
  575.     }
  576.     return (FALSE);
  577. }
  578.  
  579. /* 
  580.  * Wrapper for xdr_string that can be called directly from 
  581.  * routines like clnt_call
  582.  */
  583. bool_t
  584. xdr_wrapstring(xdrs, cpp)
  585.     XDR *xdrs;
  586.     char **cpp;
  587. {
  588.     if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
  589.         return (TRUE);
  590.     }
  591.     return (FALSE);
  592. }
  593. Funky_Stuff
  594. len=`wc -c < xdr.c`
  595. if [ $len !=    11049 ] ; then
  596.   echo error: xdr.c was $len bytes long, should have been    11049
  597. fi
  598. echo x - xdr.h
  599. cat > xdr.h <<'Funky_Stuff'
  600. /* @(#)xdr.h    1.1 87/11/04 3.9 RPCSRC */
  601. /*
  602.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  603.  * unrestricted use provided that this legend is included on all tape
  604.  * media and as a part of the software program in whole or part.  Users
  605.  * may copy or modify Sun RPC without charge, but are not authorized
  606.  * to license or distribute it to anyone else except as part of a product or
  607.  * program developed by the user.
  608.  * 
  609.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  610.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  611.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  612.  * 
  613.  * Sun RPC is provided with no support and without any obligation on the
  614.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  615.  * modification or enhancement.
  616.  * 
  617.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  618.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  619.  * OR ANY PART THEREOF.
  620.  * 
  621.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  622.  * or profits or other special, indirect and consequential damages, even if
  623.  * Sun has been advised of the possibility of such damages.
  624.  * 
  625.  * Sun Microsystems, Inc.
  626.  * 2550 Garcia Avenue
  627.  * Mountain View, California  94043
  628.  */
  629. /*      @(#)xdr.h 1.19 87/04/22 SMI      */
  630.  
  631. /*
  632.  * xdr.h, External Data Representation Serialization Routines.
  633.  *
  634.  * Copyright (C) 1984, Sun Microsystems, Inc.
  635.  */
  636.  
  637. #ifndef __XDR_HEADER__
  638. #define __XDR_HEADER__
  639.  
  640. /*
  641.  * XDR provides a conventional way for converting between C data
  642.  * types and an external bit-string representation.  Library supplied
  643.  * routines provide for the conversion on built-in C data types.  These
  644.  * routines and utility routines defined here are used to help implement
  645.  * a type encode/decode routine for each user-defined type.
  646.  *
  647.  * Each data type provides a single procedure which takes two arguments:
  648.  *
  649.  *    bool_t
  650.  *    xdrproc(xdrs, argresp)
  651.  *        XDR *xdrs;
  652.  *        <type> *argresp;
  653.  *
  654.  * xdrs is an instance of a XDR handle, to which or from which the data
  655.  * type is to be converted.  argresp is a pointer to the structure to be
  656.  * converted.  The XDR handle contains an operation field which indicates
  657.  * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
  658.  *
  659.  * XDR_DECODE may allocate space if the pointer argresp is null.  This
  660.  * data can be freed with the XDR_FREE operation.
  661.  *
  662.  * We write only one procedure per data type to make it easy
  663.  * to keep the encode and decode procedures for a data type consistent.
  664.  * In many cases the same code performs all operations on a user defined type,
  665.  * because all the hard work is done in the component type routines.
  666.  * decode as a series of calls on the nested data types.
  667.  */
  668.  
  669. /*
  670.  * Xdr operations.  XDR_ENCODE causes the type to be encoded into the
  671.  * stream.  XDR_DECODE causes the type to be extracted from the stream.
  672.  * XDR_FREE can be used to release the space allocated by an XDR_DECODE
  673.  * request.
  674.  */
  675. enum xdr_op {
  676.     XDR_ENCODE=0,
  677.     XDR_DECODE=1,
  678.     XDR_FREE=2
  679. };
  680.  
  681. /*
  682.  * This is the number of bytes per unit of external data.
  683.  */
  684. #define BYTES_PER_XDR_UNIT    (4)
  685. #define RNDUP(x)  ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
  686.             * BYTES_PER_XDR_UNIT)
  687.  
  688. /*
  689.  * A xdrproc_t exists for each data type which is to be encoded or decoded.
  690.  *
  691.  * The second argument to the xdrproc_t is a pointer to an opaque pointer.
  692.  * The opaque pointer generally points to a structure of the data type
  693.  * to be decoded.  If this pointer is 0, then the type routines should
  694.  * allocate dynamic storage of the appropriate size and return it.
  695.  * bool_t    (*xdrproc_t)(XDR *, caddr_t *);
  696.  */
  697. typedef    bool_t (*xdrproc_t)();
  698.  
  699. /*
  700.  * The XDR handle.
  701.  * Contains operation which is being applied to the stream,
  702.  * an operations vector for the paticular implementation (e.g. see xdr_mem.c),
  703.  * and two private fields for the use of the particular impelementation.
  704.  */
  705. typedef struct {
  706.     enum xdr_op    x_op;        /* operation; fast additional param */
  707.     struct xdr_ops {
  708.         bool_t    (*x_getlong)();    /* get a long from underlying stream */
  709.         bool_t    (*x_putlong)();    /* put a long to " */
  710.         bool_t    (*x_getbytes)();/* get some bytes from " */
  711.         bool_t    (*x_putbytes)();/* put some bytes to " */
  712.         u_int    (*x_getpostn)();/* returns bytes off from beginning */
  713.         bool_t  (*x_setpostn)();/* lets you reposition the stream */
  714.         long *    (*x_inline)();    /* buf quick ptr to buffered data */
  715.         void    (*x_destroy)();    /* free privates of this xdr_stream */
  716.     } *x_ops;
  717.     caddr_t     x_public;    /* users' data */
  718.     caddr_t        x_private;    /* pointer to private data */
  719.     caddr_t     x_base;        /* private used for position info */
  720.     int        x_handy;    /* extra private word */
  721. } XDR;
  722.  
  723. /*
  724.  * Operations defined on a XDR handle
  725.  *
  726.  * XDR        *xdrs;
  727.  * long        *longp;
  728.  * caddr_t     addr;
  729.  * u_int     len;
  730.  * u_int     pos;
  731.  */
  732. #define XDR_GETLONG(xdrs, longp)            \
  733.     (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
  734. #define xdr_getlong(xdrs, longp)            \
  735.     (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
  736.  
  737. #define XDR_PUTLONG(xdrs, longp)            \
  738.     (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
  739. #define xdr_putlong(xdrs, longp)            \
  740.     (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
  741.  
  742. #define XDR_GETBYTES(xdrs, addr, len)            \
  743.     (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
  744. #define xdr_getbytes(xdrs, addr, len)            \
  745.     (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
  746.  
  747. #define XDR_PUTBYTES(xdrs, addr, len)            \
  748.     (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
  749. #define xdr_putbytes(xdrs, addr, len)            \
  750.     (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
  751.  
  752. #define XDR_GETPOS(xdrs)                \
  753.     (*(xdrs)->x_ops->x_getpostn)(xdrs)
  754. #define xdr_getpos(xdrs)                \
  755.     (*(xdrs)->x_ops->x_getpostn)(xdrs)
  756.  
  757. #define XDR_SETPOS(xdrs, pos)                \
  758.     (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
  759. #define xdr_setpos(xdrs, pos)                \
  760.     (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
  761.  
  762. #define    XDR_INLINE(xdrs, len)                \
  763.     (*(xdrs)->x_ops->x_inline)(xdrs, len)
  764. #define    xdr_inline(xdrs, len)                \
  765.     (*(xdrs)->x_ops->x_inline)(xdrs, len)
  766.  
  767. #define    XDR_DESTROY(xdrs)                \
  768.     if ((xdrs)->x_ops->x_destroy)             \
  769.         (*(xdrs)->x_ops->x_destroy)(xdrs)
  770. #define    xdr_destroy(xdrs)                \
  771.     if ((xdrs)->x_ops->x_destroy)             \
  772.         (*(xdrs)->x_ops->x_destroy)(xdrs)
  773.  
  774. /*
  775.  * Support struct for discriminated unions.
  776.  * You create an array of xdrdiscrim structures, terminated with
  777.  * a entry with a null procedure pointer.  The xdr_union routine gets
  778.  * the discriminant value and then searches the array of structures
  779.  * for a matching value.  If a match is found the associated xdr routine
  780.  * is called to handle that part of the union.  If there is
  781.  * no match, then a default routine may be called.
  782.  * If there is no match and no default routine it is an error.
  783.  */
  784. #define NULL_xdrproc_t ((xdrproc_t)0)
  785. struct xdr_discrim {
  786.     int    value;
  787.     xdrproc_t proc;
  788. };
  789.  
  790. /*
  791.  * In-line routines for fast encode/decode of primitve data types.
  792.  * Caveat emptor: these use single memory cycles to get the
  793.  * data from the underlying buffer, and will fail to operate
  794.  * properly if the data is not aligned.  The standard way to use these
  795.  * is to say:
  796.  *    if ((buf = XDR_INLINE(xdrs, count)) == NULL)
  797.  *        return (FALSE);
  798.  *    <<< macro calls >>>
  799.  * where ``count'' is the number of bytes of data occupied
  800.  * by the primitive data types.
  801.  *
  802.  * N.B. and frozen for all time: each data type here uses 4 bytes
  803.  * of external representation.
  804.  */
  805. #define IXDR_GET_LONG(buf)        ((long)ntohl((u_long)*(buf)++))
  806. #define IXDR_PUT_LONG(buf, v)        (*(buf)++ = (long)htonl((u_long)v))
  807.  
  808. #define IXDR_GET_BOOL(buf)        ((bool_t)IXDR_GET_LONG(buf))
  809. #define IXDR_GET_ENUM(buf, t)        ((t)IXDR_GET_LONG(buf))
  810. #define IXDR_GET_U_LONG(buf)        ((u_long)IXDR_GET_LONG(buf))
  811. #define IXDR_GET_SHORT(buf)        ((short)IXDR_GET_LONG(buf))
  812. #define IXDR_GET_U_SHORT(buf)        ((u_short)IXDR_GET_LONG(buf))
  813.  
  814. #define IXDR_PUT_BOOL(buf, v)        IXDR_PUT_LONG((buf), ((long)(v)))
  815. #define IXDR_PUT_ENUM(buf, v)        IXDR_PUT_LONG((buf), ((long)(v)))
  816. #define IXDR_PUT_U_LONG(buf, v)        IXDR_PUT_LONG((buf), ((long)(v)))
  817. #define IXDR_PUT_SHORT(buf, v)        IXDR_PUT_LONG((buf), ((long)(v)))
  818. #define IXDR_PUT_U_SHORT(buf, v)    IXDR_PUT_LONG((buf), ((long)(v)))
  819.  
  820. /*
  821.  * These are the "generic" xdr routines.
  822.  */
  823. extern bool_t    xdr_void();
  824. extern bool_t    xdr_int();
  825. extern bool_t    xdr_u_int();
  826. extern bool_t    xdr_long();
  827. extern bool_t    xdr_u_long();
  828. extern bool_t    xdr_short();
  829. extern bool_t    xdr_u_short();
  830. extern bool_t    xdr_bool();
  831. extern bool_t    xdr_enum();
  832. extern bool_t    xdr_array();
  833. extern bool_t    xdr_bytes();
  834. extern bool_t    xdr_opaque();
  835. extern bool_t    xdr_string();
  836. extern bool_t    xdr_union();
  837. extern bool_t    xdr_char();
  838. extern bool_t    xdr_u_char();
  839. extern bool_t    xdr_vector();
  840. extern bool_t    xdr_float();
  841. extern bool_t    xdr_double();
  842. extern bool_t    xdr_reference();
  843. extern bool_t    xdr_pointer();
  844. extern bool_t    xdr_wrapstring();
  845.  
  846. /*
  847.  * Common opaque bytes objects used by many rpc protocols;
  848.  * declared here due to commonality.
  849.  */
  850. #define MAX_NETOBJ_SZ 1024 
  851. struct netobj {
  852.     u_int    n_len;
  853.     char    *n_bytes;
  854. };
  855. typedef struct netobj netobj;
  856. extern bool_t   xdr_netobj();
  857.  
  858. /*
  859.  * These are the public routines for the various implementations of
  860.  * xdr streams.
  861.  */
  862. extern void   xdrmem_create();        /* XDR using memory buffers */
  863. extern void   xdrstdio_create();    /* XDR using stdio library */
  864. extern void   xdrrec_create();        /* XDR pseudo records for tcp */
  865. extern bool_t xdrrec_endofrecord();    /* make end of xdr record */
  866. extern bool_t xdrrec_skiprecord();    /* move to beginning of next record */
  867. extern bool_t xdrrec_eof();        /* true if no more input */
  868.  
  869. #endif !__XDR_HEADER__
  870. Funky_Stuff
  871. len=`wc -c < xdr.h`
  872. if [ $len !=     9467 ] ; then
  873.   echo error: xdr.h was $len bytes long, should have been     9467
  874. fi
  875. echo x - xdr_array.c
  876. cat > xdr_array.c <<'Funky_Stuff'
  877. /* @(#)xdr_array.c    1.1 87/11/04 3.9 RPCSRC */
  878. /*
  879.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  880.  * unrestricted use provided that this legend is included on all tape
  881.  * media and as a part of the software program in whole or part.  Users
  882.  * may copy or modify Sun RPC without charge, but are not authorized
  883.  * to license or distribute it to anyone else except as part of a product or
  884.  * program developed by the user.
  885.  * 
  886.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  887.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  888.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  889.  * 
  890.  * Sun RPC is provided with no support and without any obligation on the
  891.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  892.  * modification or enhancement.
  893.  * 
  894.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  895.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  896.  * OR ANY PART THEREOF.
  897.  * 
  898.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  899.  * or profits or other special, indirect and consequential damages, even if
  900.  * Sun has been advised of the possibility of such damages.
  901.  * 
  902.  * Sun Microsystems, Inc.
  903.  * 2550 Garcia Avenue
  904.  * Mountain View, California  94043
  905.  */
  906. #if !defined(lint) && defined(SCCSIDS)
  907. static char sccsid[] = "@(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro";
  908. #endif
  909.  
  910. /*
  911.  * xdr_array.c, Generic XDR routines impelmentation.
  912.  *
  913.  * Copyright (C) 1984, Sun Microsystems, Inc.
  914.  *
  915.  * These are the "non-trivial" xdr primitives used to serialize and de-serialize
  916.  * arrays.  See xdr.h for more info on the interface to xdr.
  917.  */
  918.  
  919. #include <stdio.h>
  920.  
  921. #include <rpc/types.h>
  922. #include <rpc/xdr.h>
  923.  
  924. #define LASTUNSIGNED    ((u_int)0-1)
  925.  
  926.  
  927. /*
  928.  * XDR an array of arbitrary elements
  929.  * *addrp is a pointer to the array, *sizep is the number of elements.
  930.  * If addrp is NULL (*sizep * elsize) bytes are allocated.
  931.  * elsize is the size (in bytes) of each element, and elproc is the
  932.  * xdr procedure to call to handle each element of the array.
  933.  */
  934. bool_t
  935. xdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc)
  936.     register XDR *xdrs;
  937.     caddr_t *addrp;        /* array pointer */
  938.     u_int *sizep;        /* number of elements */
  939.     u_int maxsize;        /* max numberof elements */
  940.     u_int elsize;        /* size in bytes of each element */
  941.     xdrproc_t elproc;    /* xdr routine to handle each element */
  942. {
  943.     register u_int i;
  944.     register caddr_t target = *addrp;
  945.     register u_int c;  /* the actual element count */
  946.     register bool_t stat = TRUE;
  947.     register u_int nodesize;
  948.  
  949.     /* like strings, arrays are really counted arrays */
  950.     if (! xdr_u_int(xdrs, sizep)) {
  951.         return (FALSE);
  952.     }
  953.     c = *sizep;
  954.     if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) {
  955.         return (FALSE);
  956.     }
  957.     nodesize = c * elsize;
  958.  
  959.     /*
  960.      * if we are deserializing, we may need to allocate an array.
  961.      * We also save time by checking for a null array if we are freeing.
  962.      */
  963.     if (target == NULL)
  964.         switch (xdrs->x_op) {
  965.         case XDR_DECODE:
  966.             if (c == 0)
  967.                 return (TRUE);
  968.             *addrp = target = mem_alloc(nodesize);
  969.             if (target == NULL) {
  970.                 (void) fprintf(stderr, 
  971.                     "xdr_array: out of memory\n");
  972.                 return (FALSE);
  973.             }
  974.             bzero(target, nodesize);
  975.             break;
  976.  
  977.         case XDR_FREE:
  978.             return (TRUE);
  979.     }
  980.     
  981.     /*
  982.      * now we xdr each element of array
  983.      */
  984.     for (i = 0; (i < c) && stat; i++) {
  985.         stat = (*elproc)(xdrs, target, LASTUNSIGNED);
  986.         target += elsize;
  987.     }
  988.  
  989.     /*
  990.      * the array may need freeing
  991.      */
  992.     if (xdrs->x_op == XDR_FREE) {
  993.         mem_free(*addrp, nodesize);
  994.         *addrp = NULL;
  995.     }
  996.     return (stat);
  997. }
  998.  
  999. /*
  1000.  * xdr_vector():
  1001.  *
  1002.  * XDR a fixed length array. Unlike variable-length arrays,
  1003.  * the storage of fixed length arrays is static and unfreeable.
  1004.  * > basep: base of the array
  1005.  * > size: size of the array
  1006.  * > elemsize: size of each element
  1007.  * > xdr_elem: routine to XDR each element
  1008.  */
  1009. bool_t
  1010. xdr_vector(xdrs, basep, nelem, elemsize, xdr_elem)
  1011.     register XDR *xdrs;
  1012.     register char *basep;
  1013.     register u_int nelem;
  1014.     register u_int elemsize;
  1015.     register xdrproc_t xdr_elem;    
  1016. {
  1017.     register u_int i;
  1018.     register char *elptr;
  1019.  
  1020.     elptr = basep;
  1021.     for (i = 0; i < nelem; i++) {
  1022.         if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) {
  1023.             return(FALSE);
  1024.         }
  1025.         elptr += elemsize;
  1026.     }
  1027.     return(TRUE);    
  1028. }
  1029.  
  1030. Funky_Stuff
  1031. len=`wc -c < xdr_array.c`
  1032. if [ $len !=     4248 ] ; then
  1033.   echo error: xdr_array.c was $len bytes long, should have been     4248
  1034. fi
  1035. echo x - xdr_float.c
  1036. cat > xdr_float.c <<'Funky_Stuff'
  1037. /* @(#)xdr_float.c    1.1 87/11/04 3.9 RPCSRC */
  1038. /*
  1039.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1040.  * unrestricted use provided that this legend is included on all tape
  1041.  * media and as a part of the software program in whole or part.  Users
  1042.  * may copy or modify Sun RPC without charge, but are not authorized
  1043.  * to license or distribute it to anyone else except as part of a product or
  1044.  * program developed by the user.
  1045.  * 
  1046.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1047.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1048.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1049.  * 
  1050.  * Sun RPC is provided with no support and without any obligation on the
  1051.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1052.  * modification or enhancement.
  1053.  * 
  1054.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1055.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1056.  * OR ANY PART THEREOF.
  1057.  * 
  1058.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1059.  * or profits or other special, indirect and consequential damages, even if
  1060.  * Sun has been advised of the possibility of such damages.
  1061.  * 
  1062.  * Sun Microsystems, Inc.
  1063.  * 2550 Garcia Avenue
  1064.  * Mountain View, California  94043
  1065.  */
  1066. #if !defined(lint) && defined(SCCSIDS)
  1067. static char sccsid[] = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";
  1068. #endif
  1069.  
  1070. /*
  1071.  * xdr_float.c, Generic XDR routines impelmentation.
  1072.  *
  1073.  * Copyright (C) 1984, Sun Microsystems, Inc.
  1074.  *
  1075.  * These are the "floating point" xdr routines used to (de)serialize
  1076.  * most common data items.  See xdr.h for more info on the interface to
  1077.  * xdr.
  1078.  */
  1079.  
  1080. #include <stdio.h>
  1081.  
  1082. #include <rpc/types.h>
  1083. #include <rpc/xdr.h>
  1084.  
  1085. /*
  1086.  * NB: Not portable.
  1087.  * This routine works on Suns (Sky / 68000's) and Vaxen.
  1088.  */
  1089.  
  1090. #ifdef vax
  1091.  
  1092. /* What IEEE single precision floating point looks like on a Vax */
  1093. struct    ieee_single {
  1094.     unsigned int    mantissa: 23;
  1095.     unsigned int    exp     : 8;
  1096.     unsigned int    sign    : 1;
  1097. };
  1098.  
  1099. /* Vax single precision floating point */
  1100. struct    vax_single {
  1101.     unsigned int    mantissa1 : 7;
  1102.     unsigned int    exp       : 8;
  1103.     unsigned int    sign      : 1;
  1104.     unsigned int    mantissa2 : 16;
  1105. };
  1106.  
  1107. #define VAX_SNG_BIAS    0x81
  1108. #define IEEE_SNG_BIAS    0x7f
  1109.  
  1110. static struct sgl_limits {
  1111.     struct vax_single s;
  1112.     struct ieee_single ieee;
  1113. } sgl_limits[2] = {
  1114.     {{ 0x7f, 0xff, 0x0, 0xffff },    /* Max Vax */
  1115.     { 0x0, 0xff, 0x0 }},        /* Max IEEE */
  1116.     {{ 0x0, 0x0, 0x0, 0x0 },    /* Min Vax */
  1117.     { 0x0, 0x0, 0x0 }}        /* Min IEEE */
  1118. };
  1119. #endif /* vax */
  1120.  
  1121. bool_t
  1122. xdr_float(xdrs, fp)
  1123.     register XDR *xdrs;
  1124.     register float *fp;
  1125. {
  1126. #if !defined(mc68000) && !defined(sparc)
  1127.     struct ieee_single is;
  1128.     struct vax_single vs, *vsp;
  1129.     struct sgl_limits *lim;
  1130.     int i;
  1131. #endif
  1132.     switch (xdrs->x_op) {
  1133.  
  1134.     case XDR_ENCODE:
  1135. #if defined(mc68000) || defined(sparc)
  1136.         return (XDR_PUTLONG(xdrs, (long *)fp));
  1137. #else
  1138.         vs = *((struct vax_single *)fp);
  1139.         for (i = 0, lim = sgl_limits;
  1140.             i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
  1141.             i++, lim++) {
  1142.             if ((vs.mantissa2 == lim->s.mantissa2) &&
  1143.                 (vs.exp == lim->s.exp) &&
  1144.                 (vs.mantissa1 == lim->s.mantissa1)) {
  1145.                 is = lim->ieee;
  1146.                 goto shipit;
  1147.             }
  1148.         }
  1149.         is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
  1150.         is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
  1151.     shipit:
  1152.         is.sign = vs.sign;
  1153.         return (XDR_PUTLONG(xdrs, (long *)&is));
  1154. #endif
  1155.  
  1156.     case XDR_DECODE:
  1157. #if defined(mc68000) || defined(sparc)
  1158.         return (XDR_GETLONG(xdrs, (long *)fp));
  1159. #else
  1160.         vsp = (struct vax_single *)fp;
  1161.         if (!XDR_GETLONG(xdrs, (long *)&is))
  1162.             return (FALSE);
  1163.         for (i = 0, lim = sgl_limits;
  1164.             i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
  1165.             i++, lim++) {
  1166.             if ((is.exp == lim->ieee.exp) &&
  1167.                 (is.mantissa == lim->ieee.mantissa)) {
  1168.                 *vsp = lim->s;
  1169.                 goto doneit;
  1170.             }
  1171.         }
  1172.         vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
  1173.         vsp->mantissa2 = is.mantissa;
  1174.         vsp->mantissa1 = (is.mantissa >> 16);
  1175.     doneit:
  1176.         vsp->sign = is.sign;
  1177.         return (TRUE);
  1178. #endif
  1179.  
  1180.     case XDR_FREE:
  1181.         return (TRUE);
  1182.     }
  1183.     return (FALSE);
  1184. }
  1185.  
  1186. /*
  1187.  * This routine works on Suns (Sky / 68000's) and Vaxen.
  1188.  */
  1189.  
  1190. #ifdef vax
  1191. /* What IEEE double precision floating point looks like on a Vax */
  1192. struct    ieee_double {
  1193.     unsigned int    mantissa1 : 20;
  1194.     unsigned int    exp       : 11;
  1195.     unsigned int    sign      : 1;
  1196.     unsigned int    mantissa2 : 32;
  1197. };
  1198.  
  1199. /* Vax double precision floating point */
  1200. struct  vax_double {
  1201.     unsigned int    mantissa1 : 7;
  1202.     unsigned int    exp       : 8;
  1203.     unsigned int    sign      : 1;
  1204.     unsigned int    mantissa2 : 16;
  1205.     unsigned int    mantissa3 : 16;
  1206.     unsigned int    mantissa4 : 16;
  1207. };
  1208.  
  1209. #define VAX_DBL_BIAS    0x81
  1210. #define IEEE_DBL_BIAS    0x3ff
  1211. #define MASK(nbits)    ((1 << nbits) - 1)
  1212.  
  1213. static struct dbl_limits {
  1214.     struct    vax_double d;
  1215.     struct    ieee_double ieee;
  1216. } dbl_limits[2] = {
  1217.     {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },    /* Max Vax */
  1218.     { 0x0, 0x7ff, 0x0, 0x0 }},            /* Max IEEE */
  1219.     {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},        /* Min Vax */
  1220.     { 0x0, 0x0, 0x0, 0x0 }}                /* Min IEEE */
  1221. };
  1222.  
  1223. #endif /* vax */
  1224.  
  1225.  
  1226. bool_t
  1227. xdr_double(xdrs, dp)
  1228.     register XDR *xdrs;
  1229.     double *dp;
  1230. {
  1231.     register long *lp;
  1232. #if !defined(mc68000) && !defined(sparc)
  1233.     struct    ieee_double id;
  1234.     struct    vax_double vd;
  1235.     register struct dbl_limits *lim;
  1236.     int i;
  1237. #endif
  1238.  
  1239.     switch (xdrs->x_op) {
  1240.  
  1241.     case XDR_ENCODE:
  1242. #if defined(mc68000) || defined(sparc)
  1243.         lp = (long *)dp;
  1244. #else
  1245.         vd = *((struct vax_double *)dp);
  1246.         for (i = 0, lim = dbl_limits;
  1247.             i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
  1248.             i++, lim++) {
  1249.             if ((vd.mantissa4 == lim->d.mantissa4) &&
  1250.                 (vd.mantissa3 == lim->d.mantissa3) &&
  1251.                 (vd.mantissa2 == lim->d.mantissa2) &&
  1252.                 (vd.mantissa1 == lim->d.mantissa1) &&
  1253.                 (vd.exp == lim->d.exp)) {
  1254.                 id = lim->ieee;
  1255.                 goto shipit;
  1256.             }
  1257.         }
  1258.         id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
  1259.         id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
  1260.         id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
  1261.                 (vd.mantissa3 << 13) |
  1262.                 ((vd.mantissa4 >> 3) & MASK(13));
  1263.     shipit:
  1264.         id.sign = vd.sign;
  1265.         lp = (long *)&id;
  1266. #endif
  1267.         return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
  1268.  
  1269.     case XDR_DECODE:
  1270. #if defined(mc68000) || defined(sparc)
  1271.         lp = (long *)dp;
  1272.         return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
  1273. #else
  1274.         lp = (long *)&id;
  1275.         if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
  1276.             return (FALSE);
  1277.         for (i = 0, lim = dbl_limits;
  1278.             i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
  1279.             i++, lim++) {
  1280.             if ((id.mantissa2 == lim->ieee.mantissa2) &&
  1281.                 (id.mantissa1 == lim->ieee.mantissa1) &&
  1282.                 (id.exp == lim->ieee.exp)) {
  1283.                 vd = lim->d;
  1284.                 goto doneit;
  1285.             }
  1286.         }
  1287.         vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
  1288.         vd.mantissa1 = (id.mantissa1 >> 13);
  1289.         vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
  1290.                 (id.mantissa2 >> 29);
  1291.         vd.mantissa3 = (id.mantissa2 >> 13);
  1292.         vd.mantissa4 = (id.mantissa2 << 3);
  1293.     doneit:
  1294.         vd.sign = id.sign;
  1295.         *dp = *((double *)&vd);
  1296.         return (TRUE);
  1297. #endif
  1298.  
  1299.     case XDR_FREE:
  1300.         return (TRUE);
  1301.     }
  1302.     return (FALSE);
  1303. }
  1304. Funky_Stuff
  1305. len=`wc -c < xdr_float.c`
  1306. if [ $len !=     6921 ] ; then
  1307.   echo error: xdr_float.c was $len bytes long, should have been     6921
  1308. fi
  1309. echo x - xdr_mem.c
  1310. cat > xdr_mem.c <<'Funky_Stuff'
  1311. /* @(#)xdr_mem.c    1.1 87/11/04 3.9 RPCSRC */
  1312. /*
  1313.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1314.  * unrestricted use provided that this legend is included on all tape
  1315.  * media and as a part of the software program in whole or part.  Users
  1316.  * may copy or modify Sun RPC without charge, but are not authorized
  1317.  * to license or distribute it to anyone else except as part of a product or
  1318.  * program developed by the user.
  1319.  * 
  1320.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1321.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1322.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1323.  * 
  1324.  * Sun RPC is provided with no support and without any obligation on the
  1325.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1326.  * modification or enhancement.
  1327.  * 
  1328.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1329.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1330.  * OR ANY PART THEREOF.
  1331.  * 
  1332.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1333.  * or profits or other special, indirect and consequential damages, even if
  1334.  * Sun has been advised of the possibility of such damages.
  1335.  * 
  1336.  * Sun Microsystems, Inc.
  1337.  * 2550 Garcia Avenue
  1338.  * Mountain View, California  94043
  1339.  */
  1340. #if !defined(lint) && defined(SCCSIDS)
  1341. static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
  1342. #endif
  1343.  
  1344. /*
  1345.  * xdr_mem.h, XDR implementation using memory buffers.
  1346.  *
  1347.  * Copyright (C) 1984, Sun Microsystems, Inc.
  1348.  *
  1349.  * If you have some data to be interpreted as external data representation
  1350.  * or to be converted to external data representation in a memory buffer,
  1351.  * then this is the package for you.
  1352.  *
  1353.  */
  1354.  
  1355.  
  1356. #include <rpc/types.h>
  1357. #include <rpc/xdr.h>
  1358. #include <netinet/in.h>
  1359.  
  1360. static bool_t    xdrmem_getlong();
  1361. static bool_t    xdrmem_putlong();
  1362. static bool_t    xdrmem_getbytes();
  1363. static bool_t    xdrmem_putbytes();
  1364. static u_int    xdrmem_getpos();
  1365. static bool_t    xdrmem_setpos();
  1366. static long *    xdrmem_inline();
  1367. static void    xdrmem_destroy();
  1368.  
  1369. static struct    xdr_ops xdrmem_ops = {
  1370.     xdrmem_getlong,
  1371.     xdrmem_putlong,
  1372.     xdrmem_getbytes,
  1373.     xdrmem_putbytes,
  1374.     xdrmem_getpos,
  1375.     xdrmem_setpos,
  1376.     xdrmem_inline,
  1377.     xdrmem_destroy
  1378. };
  1379.  
  1380. /*
  1381.  * The procedure xdrmem_create initializes a stream descriptor for a
  1382.  * memory buffer.  
  1383.  */
  1384. void
  1385. xdrmem_create(xdrs, addr, size, op)
  1386.     register XDR *xdrs;
  1387.     caddr_t addr;
  1388.     u_int size;
  1389.     enum xdr_op op;
  1390. {
  1391.  
  1392.     xdrs->x_op = op;
  1393.     xdrs->x_ops = &xdrmem_ops;
  1394.     xdrs->x_private = xdrs->x_base = addr;
  1395.     xdrs->x_handy = size;
  1396. }
  1397.  
  1398. static void
  1399. xdrmem_destroy(/*xdrs*/)
  1400.     /*XDR *xdrs;*/
  1401. {
  1402. }
  1403.  
  1404. static bool_t
  1405. xdrmem_getlong(xdrs, lp)
  1406.     register XDR *xdrs;
  1407.     long *lp;
  1408. {
  1409.  
  1410.     if ((xdrs->x_handy -= sizeof(long)) < 0)
  1411.         return (FALSE);
  1412.     *lp = (long)ntohl((u_long)(*((long *)(xdrs->x_private))));
  1413.     xdrs->x_private += sizeof(long);
  1414.     return (TRUE);
  1415. }
  1416.  
  1417. static bool_t
  1418. xdrmem_putlong(xdrs, lp)
  1419.     register XDR *xdrs;
  1420.     long *lp;
  1421. {
  1422.  
  1423.     if ((xdrs->x_handy -= sizeof(long)) < 0)
  1424.         return (FALSE);
  1425.     *(long *)xdrs->x_private = (long)htonl((u_long)(*lp));
  1426.     xdrs->x_private += sizeof(long);
  1427.     return (TRUE);
  1428. }
  1429.  
  1430. static bool_t
  1431. xdrmem_getbytes(xdrs, addr, len)
  1432.     register XDR *xdrs;
  1433.     caddr_t addr;
  1434.     register u_int len;
  1435. {
  1436.  
  1437.     if ((xdrs->x_handy -= len) < 0)
  1438.         return (FALSE);
  1439.     bcopy(xdrs->x_private, addr, len);
  1440.     xdrs->x_private += len;
  1441.     return (TRUE);
  1442. }
  1443.  
  1444. static bool_t
  1445. xdrmem_putbytes(xdrs, addr, len)
  1446.     register XDR *xdrs;
  1447.     caddr_t addr;
  1448.     register u_int len;
  1449. {
  1450.  
  1451.     if ((xdrs->x_handy -= len) < 0)
  1452.         return (FALSE);
  1453.     bcopy(addr, xdrs->x_private, len);
  1454.     xdrs->x_private += len;
  1455.     return (TRUE);
  1456. }
  1457.  
  1458. static u_int
  1459. xdrmem_getpos(xdrs)
  1460.     register XDR *xdrs;
  1461. {
  1462.  
  1463.     return ((u_int)xdrs->x_private - (u_int)xdrs->x_base);
  1464. }
  1465.  
  1466. static bool_t
  1467. xdrmem_setpos(xdrs, pos)
  1468.     register XDR *xdrs;
  1469.     u_int pos;
  1470. {
  1471.     register caddr_t newaddr = xdrs->x_base + pos;
  1472.     register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
  1473.  
  1474.     if ((long)newaddr > (long)lastaddr)
  1475.         return (FALSE);
  1476.     xdrs->x_private = newaddr;
  1477.     xdrs->x_handy = (int)lastaddr - (int)newaddr;
  1478.     return (TRUE);
  1479. }
  1480.  
  1481. static long *
  1482. xdrmem_inline(xdrs, len)
  1483.     register XDR *xdrs;
  1484.     int len;
  1485. {
  1486.     long *buf = 0;
  1487.  
  1488.     if (xdrs->x_handy >= len) {
  1489.         xdrs->x_handy -= len;
  1490.         buf = (long *) xdrs->x_private;
  1491.         xdrs->x_private += len;
  1492.     }
  1493.     return (buf);
  1494. }
  1495. Funky_Stuff
  1496. len=`wc -c < xdr_mem.c`
  1497. if [ $len !=     4251 ] ; then
  1498.   echo error: xdr_mem.c was $len bytes long, should have been     4251
  1499. fi
  1500. echo x - xdr_rec.c
  1501. cat > xdr_rec.c <<'Funky_Stuff'
  1502. /* @(#)xdr_rec.c    1.1 87/11/04 3.9 RPCSRC */
  1503. /*
  1504.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1505.  * unrestricted use provided that this legend is included on all tape
  1506.  * media and as a part of the software program in whole or part.  Users
  1507.  * may copy or modify Sun RPC without charge, but are not authorized
  1508.  * to license or distribute it to anyone else except as part of a product or
  1509.  * program developed by the user.
  1510.  * 
  1511.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1512.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1513.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1514.  * 
  1515.  * Sun RPC is provided with no support and without any obligation on the
  1516.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1517.  * modification or enhancement.
  1518.  * 
  1519.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1520.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1521.  * OR ANY PART THEREOF.
  1522.  * 
  1523.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1524.  * or profits or other special, indirect and consequential damages, even if
  1525.  * Sun has been advised of the possibility of such damages.
  1526.  * 
  1527.  * Sun Microsystems, Inc.
  1528.  * 2550 Garcia Avenue
  1529.  * Mountain View, California  94043
  1530.  */
  1531. #if !defined(lint) && defined(SCCSIDS)
  1532. static char sccsid[] = "@(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro";
  1533. #endif
  1534.  
  1535. /*
  1536.  * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking"
  1537.  * layer above tcp (for rpc's use).
  1538.  *
  1539.  * Copyright (C) 1984, Sun Microsystems, Inc.
  1540.  *
  1541.  * These routines interface XDRSTREAMS to a tcp/ip connection.
  1542.  * There is a record marking layer between the xdr stream
  1543.  * and the tcp transport level.  A record is composed on one or more
  1544.  * record fragments.  A record fragment is a thirty-two bit header followed
  1545.  * by n bytes of data, where n is contained in the header.  The header
  1546.  * is represented as a htonl(u_long).  Thegh order bit encodes
  1547.  * whether or not the fragment is the last fragment of the record
  1548.  * (1 => fragment is last, 0 => more fragments to follow. 
  1549.  * The other 31 bits encode the byte length of the fragment.
  1550.  */
  1551.  
  1552. #include <stdio.h>
  1553. #include <rpc/types.h>
  1554. #include <rpc/xdr.h>
  1555. #include <sys/time.h>
  1556. #include <netinet/in.h>
  1557.  
  1558. extern long    lseek();
  1559.  
  1560. static u_int    fix_buf_size();
  1561.  
  1562. static bool_t    xdrrec_getlong();
  1563. static bool_t    xdrrec_putlong();
  1564. static bool_t    xdrrec_getbytes();
  1565. static bool_t    xdrrec_putbytes();
  1566. static u_int    xdrrec_getpos();
  1567. static bool_t    xdrrec_setpos();
  1568. static long *    xdrrec_inline();
  1569. static void    xdrrec_destroy();
  1570.  
  1571. static struct  xdr_ops xdrrec_ops = {
  1572.     xdrrec_getlong,
  1573.     xdrrec_putlong,
  1574.     xdrrec_getbytes,
  1575.     xdrrec_putbytes,
  1576.     xdrrec_getpos,
  1577.     xdrrec_setpos,
  1578.     xdrrec_inline,
  1579.     xdrrec_destroy
  1580. };
  1581.  
  1582. /*
  1583.  * A record is composed of one or more record fragments.
  1584.  * A record fragment is a two-byte header followed by zero to
  1585.  * 2**32-1 bytes.  The header is treated as a long unsigned and is
  1586.  * encode/decoded to the network via htonl/ntohl.  The low order 31 bits
  1587.  * are a byte count of the fragment.  The highest order bit is a boolean:
  1588.  * 1 => this fragment is the last fragment of the record,
  1589.  * 0 => this fragment is followed by more fragment(s).
  1590.  *
  1591.  * The fragment/record machinery is not general;  it is constructed to
  1592.  * meet the needs of xdr and rpc based on tcp.
  1593.  */
  1594.  
  1595. #define LAST_FRAG ((u_long)(1 << 31))
  1596.  
  1597. typedef struct rec_strm {
  1598.     caddr_t tcp_handle;
  1599.     caddr_t the_buffer;
  1600.     /*
  1601.      * out-goung bits
  1602.      */
  1603.     int (*writeit)();
  1604.     caddr_t out_base;    /* output buffer (points to frag header) */
  1605.     caddr_t out_finger;    /* next output position */
  1606.     caddr_t out_boundry;    /* data cannot up to this address */
  1607.     u_long *frag_header;    /* beginning of curren fragment */
  1608.     bool_t frag_sent;    /* true if buffer sent in middle of record */
  1609.     /*
  1610.      * in-coming bits
  1611.      */
  1612.     int (*readit)();
  1613.     u_long in_size;    /* fixed size of the input buffer */
  1614.     caddr_t in_base;
  1615.     caddr_t in_finger;    /* location of next byte to be had */
  1616.     caddr_t in_boundry;    /* can read up to this location */
  1617.     long fbtbc;        /* fragment bytes to be consumed */
  1618.     bool_t last_frag;
  1619.     u_int sendsize;
  1620.     u_int recvsize;
  1621. } RECSTREAM;
  1622.  
  1623.  
  1624. /*
  1625.  * Create an xdr handle for xdrrec
  1626.  * xdrrec_create fills in xdrs.  Sendsize and recvsize are
  1627.  * send and recv buffer sizes (0 => use default).
  1628.  * tcp_handle is an opaque handle that is passed as the first parameter to
  1629.  * the procedures readit and writeit.  Readit and writeit are read and
  1630.  * write respectively.   They are like the system
  1631.  * calls expect that they take an opaque handle rather than an fd.
  1632.  */
  1633. void
  1634. xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit)
  1635.     register XDR *xdrs;
  1636.     register u_int sendsize;
  1637.     register u_int recvsize;
  1638.     caddr_t tcp_handle;
  1639.     int (*readit)();  /* like read, but pass it a tcp_handle, not sock */
  1640.     int (*writeit)();  /* like write, but pass it a tcp_handle, not sock */
  1641. {
  1642.     register RECSTREAM *rstrm =
  1643.         (RECSTREAM *)mem_alloc(sizeof(RECSTREAM));
  1644.  
  1645.     if (rstrm == NULL) {
  1646.         (void)fprintf(stderr, "xdrrec_create: out of memory\n");
  1647.         /* 
  1648.          *  This is bad.  Should rework xdrrec_create to 
  1649.          *  return a handle, and in this case return NULL
  1650.          */
  1651.         return;
  1652.     }
  1653.     /*
  1654.      * adjust sizes and allocate buffer quad byte aligned
  1655.      */
  1656.     rstrm->sendsize = sendsize = fix_buf_size(sendsize);
  1657.     rstrm->recvsize = recvsize = fix_buf_size(recvsize);
  1658.     rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT);
  1659.     if (rstrm->the_buffer == NULL) {
  1660.         (void)fprintf(stderr, "xdrrec_create: out of memory\n");
  1661.         return;
  1662.     }
  1663.     for (rstrm->out_base = rstrm->the_buffer;
  1664.         (u_int)rstrm->out_base % BYTES_PER_XDR_UNIT != 0;
  1665.         rstrm->out_base++);
  1666.     rstrm->in_base = rstrm->out_base + sendsize;
  1667.     /*
  1668.      * now the rest ...
  1669.      */
  1670.     xdrs->x_ops = &xdrrec_ops;
  1671.     xdrs->x_private = (caddr_t)rstrm;
  1672.     rstrm->tcp_handle = tcp_handle;
  1673.     rstrm->readit = readit;
  1674.     rstrm->writeit = writeit;
  1675.     rstrm->out_finger = rstrm->out_boundry = rstrm->out_base;
  1676.     rstrm->frag_header = (u_long *)rstrm->out_base;
  1677.     rstrm->out_finger += sizeof(u_long);
  1678.     rstrm->out_boundry += sendsize;
  1679.     rstrm->frag_sent = FALSE;
  1680.     rstrm->in_size = recvsize;
  1681.     rstrm->in_boundry = rstrm->in_base;
  1682.     rstrm->in_finger = (rstrm->in_boundry += recvsize);
  1683.     rstrm->fbtbc = 0;
  1684.     rstrm->last_frag = TRUE;
  1685. }
  1686.  
  1687.  
  1688. /*
  1689.  * The reoutines defined below are the xdr ops which will go into the
  1690.  * xdr handle filled in by xdrrec_create.
  1691.  */
  1692.  
  1693. static bool_t
  1694. xdrrec_getlong(xdrs, lp)
  1695.     XDR *xdrs;
  1696.     long *lp;
  1697. {
  1698.     register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
  1699.     register long *buflp = (long *)(rstrm->in_finger);
  1700.     long mylong;
  1701.  
  1702.     /* first try the inline, fast case */
  1703.     if ((rstrm->fbtbc >= sizeof(long)) &&
  1704.         (((int)rstrm->in_boundry - (int)buflp) >= sizeof(long))) {
  1705.         *lp = (long)ntohl((u_long)(*buflp));
  1706.         rstrm->fbtbc -= sizeof(long);
  1707.         rstrm->in_finger += sizeof(long);
  1708.     } else {
  1709.         if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long)))
  1710.             return (FALSE);
  1711.         *lp = (long)ntohl((u_long)mylong);
  1712.     }
  1713.     return (TRUE);
  1714. }
  1715.  
  1716. static bool_t
  1717. xdrrec_putlong(xdrs, lp)
  1718.     XDR *xdrs;
  1719.     long *lp;
  1720. {
  1721.     register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
  1722.     register long *dest_lp = ((long *)(rstrm->out_finger));
  1723.  
  1724.     if ((rstrm->out_finger += sizeof(long)) > rstrm->out_boundry) {
  1725.         /*
  1726.          * this case should almost never happen so the code is
  1727.          * inefficient
  1728.          */
  1729.         rstrm->out_finger -= sizeof(long);
  1730.         rstrm->frag_sent = TRUE;
  1731.         if (! flush_out(rstrm, FALSE))
  1732.             return (FALSE);
  1733.         dest_lp = ((long *)(rstrm->out_finger));
  1734.         rstrm->out_finger += sizeof(long);
  1735.     }
  1736.     *dest_lp = (long)htonl((u_long)(*lp));
  1737.     return (TRUE);
  1738. }
  1739.  
  1740. static bool_t  /* must manage buffers, fragments, and records */
  1741. xdrrec_getbytes(xdrs, addr, len)
  1742.     XDR *xdrs;
  1743.     register caddr_t addr;
  1744.     register u_int len;
  1745. {
  1746.     register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
  1747.     register int current;
  1748.  
  1749.     while (len > 0) {
  1750.         current = rstrm->fbtbc;
  1751.         if (current == 0) {
  1752.             if (rstrm->last_frag)
  1753.                 return (FALSE);
  1754.             if (! set_input_fragment(rstrm))
  1755.                 return (FALSE);
  1756.             continue;
  1757.         }
  1758.         current = (len < current) ? len : current;
  1759.         if (! get_input_bytes(rstrm, addr, current))
  1760.             return (FALSE);
  1761.         addr += current; 
  1762.         rstrm->fbtbc -= current;
  1763.         len -= current;
  1764.     }
  1765.     return (TRUE);
  1766. }
  1767.  
  1768. static bool_t
  1769. xdrrec_putbytes(xdrs, addr, len)
  1770.     XDR *xdrs;
  1771.     register caddr_t addr;
  1772.     register u_int len;
  1773. {
  1774.     register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
  1775.     register int current;
  1776.  
  1777.     while (len > 0) {
  1778.         current = (u_int)rstrm->out_boundry - (u_int)rstrm->out_finger;
  1779.         current = (len < current) ? len : current;
  1780.         bcopy(addr, rstrm->out_finger, current);
  1781.         rstrm->out_finger += current;
  1782.         addr += current;
  1783.         len -= current;
  1784.         if (rstrm->out_finger == rstrm->out_boundry) {
  1785.             rstrm->frag_sent = TRUE;
  1786.             if (! flush_out(rstrm, FALSE))
  1787.                 return (FALSE);
  1788.         }
  1789.     }
  1790.     return (TRUE);
  1791. }
  1792.  
  1793. static u_int
  1794. xdrrec_getpos(xdrs)
  1795.     register XDR *xdrs;
  1796. {
  1797.     register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
  1798.     register long pos;
  1799.  
  1800.     pos = lseek((int)rstrm->tcp_handle, (long) 0, 1);
  1801.     if (pos != -1)
  1802.         switch (xdrs->x_op) {
  1803.  
  1804.         case XDR_ENCODE:
  1805.             pos += rstrm->out_finger - rstrm->out_base;
  1806.             break;
  1807.  
  1808.         case XDR_DECODE:
  1809.             pos -= rstrm->in_boundry - rstrm->in_finger;
  1810.             break;
  1811.  
  1812.         default:
  1813.             pos = (u_int) -1;
  1814.             break;
  1815.         }
  1816.     return ((u_int) pos);
  1817. }
  1818.  
  1819. static bool_t
  1820. xdrrec_setpos(xdrs, pos)
  1821.     register XDR *xdrs;
  1822.     u_int pos;
  1823. {
  1824.     register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
  1825.     u_int currpos = xdrrec_getpos(xdrs);
  1826.     int delta = currpos - pos;
  1827.     caddr_t newpos;
  1828.  
  1829.     if ((int)currpos != -1)
  1830.         switch (xdrs->x_op) {
  1831.  
  1832.         case XDR_ENCODE:
  1833.             newpos = rstrm->out_finger - delta;
  1834.             if ((newpos > (caddr_t)(rstrm->frag_header)) &&
  1835.                 (newpos < rstrm->out_boundry)) {
  1836.                 rstrm->out_finger = newpos;
  1837.                 return (TRUE);
  1838.             }
  1839.             break;
  1840.  
  1841.         case XDR_DECODE:
  1842.             newpos = rstrm->in_finger - delta;
  1843.             if ((delta < (int)(rstrm->fbtbc)) &&
  1844.                 (newpos <= rstrm->in_boundry) &&
  1845.                 (newpos >= rstrm->in_base)) {
  1846.                 rstrm->in_finger = newpos;
  1847.                 rstrm->fbtbc -= delta;
  1848.                 return (TRUE);
  1849.             }
  1850.             break;
  1851.         }
  1852.     return (FALSE);
  1853. }
  1854.  
  1855. static long *
  1856. xdrrec_inline(xdrs, len)
  1857.     register XDR *xdrs;
  1858.     int len;
  1859. {
  1860.     register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
  1861.     long * buf = NULL;
  1862.  
  1863.     switch (xdrs->x_op) {
  1864.  
  1865.     case XDR_ENCODE:
  1866.         if ((rstrm->out_finger + len) <= rstrm->out_boundry) {
  1867.             buf = (long *) rstrm->out_finger;
  1868.             rstrm->out_finger += len;
  1869.         }
  1870.         break;
  1871.  
  1872.     case XDR_DECODE:
  1873.         if ((len <= rstrm->fbtbc) &&
  1874.             ((rstrm->in_finger + len) <= rstrm->in_boundry)) {
  1875.             buf = (long *) rstrm->in_finger;
  1876.             rstrm->fbtbc -= len;
  1877.             rstrm->in_finger += len;
  1878.         }
  1879.         break;
  1880.     }
  1881.     return (buf);
  1882. }
  1883.  
  1884. static void
  1885. xdrrec_destroy(xdrs)
  1886.     register XDR *xdrs;
  1887. {
  1888.     register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
  1889.  
  1890.     mem_free(rstrm->the_buffer,
  1891.         rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT);
  1892.     mem_free((caddr_t)rstrm, sizeof(RECSTREAM));
  1893. }
  1894.  
  1895.  
  1896. /*
  1897.  * Exported routines to manage xdr records
  1898.  */
  1899.  
  1900. /*
  1901.  * Before reading (deserializing from the stream, one should always call
  1902.  * this procedure to guarantee proper record alignment.
  1903.  */
  1904. bool_t
  1905. xdrrec_skiprecord(xdrs)
  1906.     XDR *xdrs;
  1907. {
  1908.     register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
  1909.  
  1910.     while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
  1911.         if (! skip_input_bytes(rstrm, rstrm->fbtbc))
  1912.             return (FALSE);
  1913.         rstrm->fbtbc = 0;
  1914.         if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
  1915.             return (FALSE);
  1916.     }
  1917.     rstrm->last_frag = FALSE;
  1918.     return (TRUE);
  1919. }
  1920.  
  1921. /*
  1922.  * Look ahead fuction.
  1923.  * Returns TRUE iff there is no more input in the buffer 
  1924.  * after consuming the rest of the current record.
  1925.  */
  1926. bool_t
  1927. xdrrec_eof(xdrs)
  1928.     XDR *xdrs;
  1929. {
  1930.     register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
  1931.  
  1932.     while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
  1933.         if (! skip_input_bytes(rstrm, rstrm->fbtbc))
  1934.             return (TRUE);
  1935.         rstrm->fbtbc = 0;
  1936.         if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
  1937.             return (TRUE);
  1938.     }
  1939.     if (rstrm->in_finger == rstrm->in_boundry)
  1940.         return (TRUE);
  1941.     return (FALSE);
  1942. }
  1943.  
  1944. /*
  1945.  * The client must tell the package when an end-of-record has occurred.
  1946.  * The second paraemters tells whether the record should be flushed to the
  1947.  * (output) tcp stream.  (This let's the package support batched or
  1948.  * pipelined procedure calls.)  TRUE => immmediate flush to tcp connection.
  1949.  */
  1950. bool_t
  1951. xdrrec_endofrecord(xdrs, sendnow)
  1952.     XDR *xdrs;
  1953.     bool_t sendnow;
  1954. {
  1955.     register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
  1956.     register u_long len;  /* fragment length */
  1957.  
  1958.     if (sendnow || rstrm->frag_sent ||
  1959.         ((u_long)rstrm->out_finger + sizeof(u_long) >=
  1960.         (u_long)rstrm->out_boundry)) {
  1961.         rstrm->frag_sent = FALSE;
  1962.         return (flush_out(rstrm, TRUE));
  1963.     }
  1964.     len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) -
  1965.        sizeof(u_long);
  1966.     *(rstrm->frag_header) = htonl((u_long)len | LAST_FRAG);
  1967.     rstrm->frag_header = (u_long *)rstrm->out_finger;
  1968.     rstrm->out_finger += sizeof(u_long);
  1969.     return (TRUE);
  1970. }
  1971.  
  1972.  
  1973. /*
  1974.  * Internal useful routines
  1975.  */
  1976. static bool_t
  1977. flush_out(rstrm, eor)
  1978.     register RECSTREAM *rstrm;
  1979.     bool_t eor;
  1980. {
  1981.     register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0;
  1982.     register u_long len = (u_long)(rstrm->out_finger) - 
  1983.         (u_long)(rstrm->frag_header) - sizeof(u_long);
  1984.  
  1985.     *(rstrm->frag_header) = htonl(len | eormask);
  1986.     len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base);
  1987.     if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len)
  1988.         != (int)len)
  1989.         return (FALSE);
  1990.     rstrm->frag_header = (u_long *)rstrm->out_base;
  1991.     rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_long);
  1992.     return (TRUE);
  1993. }
  1994.  
  1995. static bool_t  /* knows nothing about records!  Only about input buffers */
  1996. fill_input_buf(rstrm)
  1997.     register RECSTREAM *rstrm;
  1998. {
  1999.     register caddr_t where;
  2000.     u_int i;
  2001.     register int len;
  2002.  
  2003.     where = rstrm->in_base;
  2004.     i = (u_int)rstrm->in_boundry % BYTES_PER_XDR_UNIT;
  2005.     where += i;
  2006.     len = rstrm->in_size - i;
  2007.     if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1)
  2008.         return (FALSE);
  2009.     rstrm->in_finger = where;
  2010.     where += len;
  2011.     rstrm->in_boundry = where;
  2012.     return (TRUE);
  2013. }
  2014.  
  2015. static bool_t  /* knows nothing about records!  Only about input buffers */
  2016. get_input_bytes(rstrm, addr, len)
  2017.     register RECSTREAM *rstrm;
  2018.     register caddr_t addr;
  2019.     register int len;
  2020. {
  2021.     register int current;
  2022.  
  2023.     while (len > 0) {
  2024.         current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
  2025.         if (current == 0) {
  2026.             if (! fill_input_buf(rstrm))
  2027.                 return (FALSE);
  2028.             continue;
  2029.         }
  2030.         current = (len < current) ? len : current;
  2031.         bcopy(rstrm->in_finger, addr, current);
  2032.         rstrm->in_finger += current;
  2033.         addr += current;
  2034.         len -= current;
  2035.     }
  2036.     return (TRUE);
  2037. }
  2038.  
  2039. static bool_t  /* next two bytes of the input stream are treated as a header */
  2040. set_input_fragment(rstrm)
  2041.     register RECSTREAM *rstrm;
  2042. {
  2043.     u_long header;
  2044.  
  2045.     if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header)))
  2046.         return (FALSE);
  2047.     header = (long)ntohl(header);
  2048.     rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE;
  2049.     rstrm->fbtbc = header & (~LAST_FRAG);
  2050.     return (TRUE);
  2051. }
  2052.  
  2053. static bool_t  /* consumes input bytes; knows nothing about records! */
  2054. skip_input_bytes(rstrm, cnt)
  2055.     register RECSTREAM *rstrm;
  2056.     long cnt;
  2057. {
  2058.     register int current;
  2059.  
  2060.     while (cnt > 0) {
  2061.         current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
  2062.         if (current == 0) {
  2063.             if (! fill_input_buf(rstrm))
  2064.                 return (FALSE);
  2065.             continue;
  2066.         }
  2067.         current = (cnt < current) ? cnt : current;
  2068.         rstrm->in_finger += current;
  2069.         cnt -= current;
  2070.     }
  2071.     return (TRUE);
  2072. }
  2073.  
  2074. static u_int
  2075. fix_buf_size(s)
  2076.     register u_int s;
  2077. {
  2078.  
  2079.     if (s < 100)
  2080.         s = 4000;
  2081.     return (RNDUP(s));
  2082. }
  2083. Funky_Stuff
  2084. len=`wc -c < xdr_rec.c`
  2085. if [ $len !=    15385 ] ; then
  2086.   echo error: xdr_rec.c was $len bytes long, should have been    15385
  2087. fi
  2088. echo x - xdr_reference.c
  2089. cat > xdr_reference.c <<'Funky_Stuff'
  2090. /* @(#)xdr_reference.c    1.1 87/11/04 3.9 RPCSRC */
  2091. /*
  2092.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  2093.  * unrestricted use provided that this legend is included on all tape
  2094.  * media and as a part of the software program in whole or part.  Users
  2095.  * may copy or modify Sun RPC without charge, but are not authorized
  2096.  * to license or distribute it to anyone else except as part of a product or
  2097.  * program developed by the user.
  2098.  * 
  2099.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  2100.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  2101.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  2102.  * 
  2103.  * Sun RPC is provided with no support and without any obligation on the
  2104.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  2105.  * modification or enhancement.
  2106.  * 
  2107.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  2108.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  2109.  * OR ANY PART THEREOF.
  2110.  * 
  2111.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  2112.  * or profits or other special, indirect and consequential damages, even if
  2113.  * Sun has been advised of the possibility of such damages.
  2114.  * 
  2115.  * Sun Microsystems, Inc.
  2116.  * 2550 Garcia Avenue
  2117.  * Mountain View, California  94043
  2118.  */
  2119. #if !defined(lint) && defined(SCCSIDS)
  2120. static char sccsid[] = "@(#)xdr_reference.c 1.11 87/08/11 SMI";
  2121. #endif
  2122.  
  2123. /*
  2124.  * xdr_reference.c, Generic XDR routines impelmentation.
  2125.  *
  2126.  * Copyright (C) 1987, Sun Microsystems, Inc.
  2127.  *
  2128.  * These are the "non-trivial" xdr primitives used to serialize and de-serialize
  2129.  * "pointers".  See xdr.h for more info on the interface to xdr.
  2130.  */
  2131.  
  2132. #include <stdio.h>
  2133. #include <rpc/types.h>
  2134. #include <rpc/xdr.h>
  2135.  
  2136. #define LASTUNSIGNED    ((u_int)0-1)
  2137.  
  2138. /*
  2139.  * XDR an indirect pointer
  2140.  * xdr_reference is for recursively translating a structure that is
  2141.  * referenced by a pointer inside the structure that is currently being
  2142.  * translated.  pp references a pointer to storage. If *pp is null
  2143.  * the  necessary storage is allocated.
  2144.  * size is the sizeof the referneced structure.
  2145.  * proc is the routine to handle the referenced structure.
  2146.  */
  2147. bool_t
  2148. xdr_reference(xdrs, pp, size, proc)
  2149.     register XDR *xdrs;
  2150.     caddr_t *pp;        /* the pointer to work on */
  2151.     u_int size;        /* size of the object pointed to */
  2152.     xdrproc_t proc;        /* xdr routine to handle the object */
  2153. {
  2154.     register caddr_t loc = *pp;
  2155.     register bool_t stat;
  2156.  
  2157.     if (loc == NULL)
  2158.         switch (xdrs->x_op) {
  2159.         case XDR_FREE:
  2160.             return (TRUE);
  2161.  
  2162.         case XDR_DECODE:
  2163.             *pp = loc = (caddr_t) mem_alloc(size);
  2164.             if (loc == NULL) {
  2165.                 (void) fprintf(stderr,
  2166.                     "xdr_reference: out of memory\n");
  2167.                 return (FALSE);
  2168.             }
  2169.             bzero(loc, (int)size);
  2170.             break;
  2171.     }
  2172.  
  2173.     stat = (*proc)(xdrs, loc, LASTUNSIGNED);
  2174.  
  2175.     if (xdrs->x_op == XDR_FREE) {
  2176.         mem_free(loc, size);
  2177.         *pp = NULL;
  2178.     }
  2179.     return (stat);
  2180. }
  2181.  
  2182.  
  2183. /*
  2184.  * xdr_pointer():
  2185.  *
  2186.  * XDR a pointer to a possibly recursive data structure. This
  2187.  * differs with xdr_reference in that it can serialize/deserialiaze
  2188.  * trees correctly.
  2189.  *
  2190.  *  What's sent is actually a union:
  2191.  *
  2192.  *  union object_pointer switch (boolean b) {
  2193.  *  case TRUE: object_data data;
  2194.  *  case FALSE: void nothing;
  2195.  *  }
  2196.  *
  2197.  * > objpp: Pointer to the pointer to the object.
  2198.  * > obj_size: size of the object.
  2199.  * > xdr_obj: routine to XDR an object.
  2200.  *
  2201.  */
  2202. bool_t
  2203. xdr_pointer(xdrs,objpp,obj_size,xdr_obj)
  2204.     register XDR *xdrs;
  2205.     char **objpp;
  2206.     u_int obj_size;
  2207.     xdrproc_t xdr_obj;
  2208. {
  2209.  
  2210.     bool_t more_data;
  2211.  
  2212.     more_data = (*objpp != NULL);
  2213.     if (! xdr_bool(xdrs,&more_data)) {
  2214.         return (FALSE);
  2215.     }
  2216.     if (! more_data) {
  2217.         *objpp = NULL;
  2218.         return (TRUE);
  2219.     }
  2220.     return (xdr_reference(xdrs,objpp,obj_size,xdr_obj));
  2221. }
  2222. Funky_Stuff
  2223. len=`wc -c < xdr_reference.c`
  2224. if [ $len !=     3692 ] ; then
  2225.   echo error: xdr_reference.c was $len bytes long, should have been     3692
  2226. fi
  2227. echo x - xdr_stdio.c
  2228. cat > xdr_stdio.c <<'Funky_Stuff'
  2229. /* @(#)xdr_stdio.c    1.1 87/11/04 3.9 RPCSRC */
  2230. /*
  2231.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  2232.  * unrestricted use provided that this legend is included on all tape
  2233.  * media and as a part of the software program in whole or part.  Users
  2234.  * may copy or modify Sun RPC without charge, but are not authorized
  2235.  * to license or distribute it to anyone else except as part of a product or
  2236.  * program developed by the user.
  2237.  * 
  2238.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  2239.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  2240.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  2241.  * 
  2242.  * Sun RPC is provided with no support and without any obligation on the
  2243.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  2244.  * modification or enhancement.
  2245.  * 
  2246.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  2247.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  2248.  * OR ANY PART THEREOF.
  2249.  * 
  2250.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  2251.  * or profits or other special, indirect and consequential damages, even if
  2252.  * Sun has been advised of the possibility of such damages.
  2253.  * 
  2254.  * Sun Microsystems, Inc.
  2255.  * 2550 Garcia Avenue
  2256.  * Mountain View, California  94043
  2257.  */
  2258. #if !defined(lint) && defined(SCCSIDS)
  2259. static char sccsid[] = "@(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro";
  2260. #endif
  2261.  
  2262. /*
  2263.  * xdr_stdio.c, XDR implementation on standard i/o file.
  2264.  *
  2265.  * Copyright (C) 1984, Sun Microsystems, Inc.
  2266.  *
  2267.  * This set of routines implements a XDR on a stdio stream.
  2268.  * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
  2269.  * from the stream.
  2270.  */
  2271.  
  2272. #include <rpc/types.h>
  2273. #include <stdio.h>
  2274. #include <rpc/xdr.h>
  2275.  
  2276. static bool_t    xdrstdio_getlong();
  2277. static bool_t    xdrstdio_putlong();
  2278. static bool_t    xdrstdio_getbytes();
  2279. static bool_t    xdrstdio_putbytes();
  2280. static u_int    xdrstdio_getpos();
  2281. static bool_t    xdrstdio_setpos();
  2282. static long *    xdrstdio_inline();
  2283. static void    xdrstdio_destroy();
  2284.  
  2285. /*
  2286.  * Ops vector for stdio type XDR
  2287.  */
  2288. static struct xdr_ops    xdrstdio_ops = {
  2289.     xdrstdio_getlong,    /* deseraialize a long int */
  2290.     xdrstdio_putlong,    /* seraialize a long int */
  2291.     xdrstdio_getbytes,    /* deserialize counted bytes */
  2292.     xdrstdio_putbytes,    /* serialize counted bytes */
  2293.     xdrstdio_getpos,    /* get offset in the stream */
  2294.     xdrstdio_setpos,    /* set offset in the stream */
  2295.     xdrstdio_inline,    /* prime stream for inline macros */
  2296.     xdrstdio_destroy    /* destroy stream */
  2297. };
  2298.  
  2299. /*
  2300.  * Initialize a stdio xdr stream.
  2301.  * Sets the xdr stream handle xdrs for use on the stream file.
  2302.  * Operation flag is set to op.
  2303.  */
  2304. void
  2305. xdrstdio_create(xdrs, file, op)
  2306.     register XDR *xdrs;
  2307.     FILE *file;
  2308.     enum xdr_op op;
  2309. {
  2310.  
  2311.     xdrs->x_op = op;
  2312.     xdrs->x_ops = &xdrstdio_ops;
  2313.     xdrs->x_private = (caddr_t)file;
  2314.     xdrs->x_handy = 0;
  2315.     xdrs->x_base = 0;
  2316. }
  2317.  
  2318. /*
  2319.  * Destroy a stdio xdr stream.
  2320.  * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
  2321.  */
  2322. static void
  2323. xdrstdio_destroy(xdrs)
  2324.     register XDR *xdrs;
  2325. {
  2326.     (void)fflush((FILE *)xdrs->x_private);
  2327.     /* xx should we close the file ?? */
  2328. };
  2329.  
  2330. static bool_t
  2331. xdrstdio_getlong(xdrs, lp)
  2332.     XDR *xdrs;
  2333.     register long *lp;
  2334. {
  2335.  
  2336.     if (fread((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
  2337.         return (FALSE);
  2338. #ifndef mc68000
  2339.     *lp = ntohl(*lp);
  2340. #endif
  2341.     return (TRUE);
  2342. }
  2343.  
  2344. static bool_t
  2345. xdrstdio_putlong(xdrs, lp)
  2346.     XDR *xdrs;
  2347.     long *lp;
  2348. {
  2349.  
  2350. #ifndef mc68000
  2351.     long mycopy = htonl(*lp);
  2352.     lp = &mycopy;
  2353. #endif
  2354.     if (fwrite((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
  2355.         return (FALSE);
  2356.     return (TRUE);
  2357. }
  2358.  
  2359. static bool_t
  2360. xdrstdio_getbytes(xdrs, addr, len)
  2361.     XDR *xdrs;
  2362.     caddr_t addr;
  2363.     u_int len;
  2364. {
  2365.  
  2366.     if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
  2367.         return (FALSE);
  2368.     return (TRUE);
  2369. }
  2370.  
  2371. static bool_t
  2372. xdrstdio_putbytes(xdrs, addr, len)
  2373.     XDR *xdrs;
  2374.     caddr_t addr;
  2375.     u_int len;
  2376. {
  2377.  
  2378.     if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
  2379.         return (FALSE);
  2380.     return (TRUE);
  2381. }
  2382.  
  2383. static u_int
  2384. xdrstdio_getpos(xdrs)
  2385.     XDR *xdrs;
  2386. {
  2387.  
  2388.     return ((u_int) ftell((FILE *)xdrs->x_private));
  2389. }
  2390.  
  2391. static bool_t
  2392. xdrstdio_setpos(xdrs, pos) 
  2393.     XDR *xdrs;
  2394.     u_int pos;
  2395.  
  2396.     return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ?
  2397.         FALSE : TRUE);
  2398. }
  2399.  
  2400. static long *
  2401. xdrstdio_inline(xdrs, len)
  2402.     XDR *xdrs;
  2403.     u_int len;
  2404. {
  2405.  
  2406.     /*
  2407.      * Must do some work to implement this: must insure
  2408.      * enough data in the underlying stdio buffer,
  2409.      * that the buffer is aligned so that we can indirect through a
  2410.      * long *, and stuff this pointer in xdrs->x_buf.  Doing
  2411.      * a fread or fwrite to a scratch buffer would defeat
  2412.      * most of the gains to be had here and require storage
  2413.      * management on this buffer, so we don't do this.
  2414.      */
  2415.     return (NULL);
  2416. }
  2417. Funky_Stuff
  2418. len=`wc -c < xdr_stdio.c`
  2419. if [ $len !=     4734 ] ; then
  2420.   echo error: xdr_stdio.c was $len bytes long, should have been     4734
  2421. fi
  2422. cd ..
  2423. echo done with directory rpc
  2424. exit
  2425.